package com.tth.learn.addproperties.java1;

import org.junit.Test;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * 实现TCP网络编程
 *
 * 例题3. 从客户端发送文件给服务端，服务端保存到本地，并返回“发送成功”给客户端
 * @Author tth
 * @Date 2022/12/28 15:20
 */
public class TCPTest3 {

    /**
     * 客户端
     */
    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;
        BufferedInputStream bis = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            // 给服务端发送图片
            String serverIp = "127.0.0.1";
            int serverPort = 9900;
            socket = new Socket(InetAddress.getByName(serverIp), serverPort);
            os = socket.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream("big.png"));
            byte[] buff = new byte[1024];
            int len;
            while ((len = bis.read(buff)) != -1) {
                os.write(buff, 0, len);
            }

            // 关闭socket数据的输出，目的是通知客户端数据发送终止
            socket.shutdownOutput();
            // 接收服务端的反馈，并打印到控制台
            is = socket.getInputStream();
            baos = new ByteArrayOutputStream();
            byte[] buff2 = new byte[10];
            int len2;
            while ((len2 = is.read(buff2)) != -1) {
                System.out.println(buff2.length + "-" + len2);
                baos.write(buff2, 0, len2);
            }
            System.out.println(baos.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != baos) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != bis) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != socket) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 服务端
     */
    @Test
    public void server() {
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        BufferedOutputStream bos = null;
        OutputStream os = null;
        try {
            // 接收客户端发送来的图片，并保存到本地
            ss = new ServerSocket(9900);
            socket = ss.accept();
            is = socket.getInputStream();
            Date date = new Date();
            bos = new BufferedOutputStream(new FileOutputStream(date.getTime()+".png"));
            byte[] buff = new byte[1024];
            int len;
            // read()是一个阻塞式的方法。如果客户端socket不停止发送数据，服务端就会一直等待
            while ((len = is.read(buff)) != -1) {
                bos.write(buff, 0, len);
            }

            // 服务端给客户端反馈
            os = socket.getOutputStream();
            os.write("图片保存成功！".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != bos) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != socket) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != ss) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
